package org.teamh.connection;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import org.teamh.connection.handler.ConnectionHandler;
import org.teamh.game.Start;
import org.teamh.game.StartGame;

public class Connection implements Runnable {
	
	private Start start;
	private Socket socket;
	private DataInputStream inputStream;
	private DataOutputStream outputStream;
	//private ConnectionHandler connectionHandler; 
	//private JsonConnectionHandler jsonHandler;
	private MessageReceiver messageReceiver;
	
	private boolean online = false;

	public Connection(Start start) {
		this.start = start;
		
		messageReceiver = new ConnectionHandler(start);
	}
	
	public Connection() {
	}

	public void sendMessage(String message) {
		try {
			outputStream.writeUTF(message);
			
			if(StartGame.PRINT_MESSAGES) {
				System.out.println("Sending: " + message);
			}
		} catch(NullPointerException e) {
			System.err.println("Trying to send a message on closed socket. ");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		try {
			while (true) {
				String line = start.getConnection().getInputStream().readUTF();
				
				if(StartGame.PRINT_MESSAGES) {
					System.out.println("Received: " + line);
				}
				
				if(messageReceiver != null) {
					messageReceiver.receiveMessage(line);
				}
			}	
		} catch(IOException e) {
			if(StartGame.PRINT_MESSAGES) {
				System.out.println("Socket has been forced to close");
			}
		}
	}

	public void connect() {
		
		try {
			socket = new Socket("192.168.178.31", 30456);
			
			online = true;

			inputStream = new DataInputStream(socket.getInputStream());
			outputStream = new DataOutputStream(socket.getOutputStream());
			

		} catch (UnknownHostException e) {
			System.err.println("Cannot connect to server. Enable offline work");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		if(online) {
			new Thread(this).start();
//			connectionHandler = new ConnectionHandler(start); // Muss in LobbyController 		
//			
//			connectionHandler.start(); // start of all handlers	// Muss in LobbyController
		}		
		
	}
	
	public void reconnect() {
		close();
		
		connect();
	}
	
	public void close() {
		
		online = false;
		
		if(socket != null) {
			try {
				socket.close();
			} catch (IOException e) {
				if(StartGame.PRINT_MESSAGES) {
					System.out.println("Socket interrupted and terminated. ");
				}
			}
		}
	}

	public DataInputStream getInputStream() {
		return inputStream;
	}

	public Socket getSocket() {
		return socket;
	}
	
	public void setMessageReceiver(MessageReceiver messageReceiver) {
		this.messageReceiver = messageReceiver;
	}
	
	public MessageReceiver getMessageReceiver() {
		return messageReceiver;
	}
	
	public boolean isOnline() {
		return online;
	}
}
